package JDK常用类库.lambda;

import org.junit.Test;

import java.util.Comparator;
import java.util.function.Consumer;

/**
 * @author zx
 * @create 2023-07-31 22:43
 * Lambda格式：
 *  ->的左边：lambda形参列表(其实就是接口中的抽象方法的形参列表)
 *  ->的右边：lambda体(其实就是重写的抽象方法的方法体)
 *  lambda的本质：作为接口的实例
 *
 *  如果一个接口中,只声明了一个抽象方法,则此接口称为函数式接口; eg：Runnable、Comparator
 *  @FunctionalInterface：在一个接口上使用此注解可以检查它是否是一个函数式接口
 *
 *  Lambda表达式的使用前提：
 *  1. 方法的参数或局部变量类型必须为接口才能使用Lambda
 *  2. 接口中有且仅有一个抽象方法(@FunctionalInterface)
 */
public class LambdaTest1 {

    /**
     * 语法格式一：无参，无返回值
     */
    @Test
    public void test1(){
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("南京市江宁区");
            }
        };
        r1.run();
        System.out.println();
        Runnable r2 = () -> {
            System.out.println("西安市未央区");
        };
        r2.run();
    }

    /**
     * 语法格式二：Lambda需要一个参数，但是没有返回值
     */
    @Test
    public void test2(){
        Consumer<String> con1 = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con1.accept("西安市未央区");
        Consumer<String> con2 = (String s) -> {
            System.out.println(s);
        };
        con2.accept("南京市江宁区");
    }

    /**
     * 语法格式三：数据类型可省略，编译器可以类型推断
     */
    @Test
    public void test3(){
        Consumer<String> con1 = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con1.accept("考研上岸(目标院校)！");
        Consumer<String> con2 = (s) -> {
            System.out.println(s);
        };
        con2.accept("换更好的工作(回西安)！");
    }

    /**
     * 语法格式四：Lambda若只需要一个参数时，参数的小括号可以省略
     */
    @Test
    public void test4(){
        Consumer<String> con1 = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con1.accept("加油！");
        Consumer<String> con2 = s -> {
            System.out.println(s);
        };
        con2.accept("努力！");
    }

    /**
     * 语法格式五：Lambda需要两个或以上的参数，多条执行语句，并且可以有返回值
     */
    @Test
    public void test5(){
        Comparator<Integer> comparator1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                System.out.println(o1);
                System.out.println(o2);
                return Integer.compare(o1,o2);
            }
        };
        System.out.println(comparator1.compare(10,23));
        Comparator<Integer> comparator2 = (o1, o2) -> {
            System.out.println(o1);
            System.out.println(o2);
            return Integer.compare(o1,o2);
        };
        System.out.println(comparator2.compare(12,23));
    }

    /**
     * 语法格式六：当Lambda体只有一条语句时，return与大括号若有，都可省
     */
    @Test
    public void test6(){
        Comparator<Integer> comparator1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };
        System.out.println(comparator1.compare(10,23));
        Comparator<Integer> comparator2 = (o1,o2) -> o1.compareTo(o2);
        System.out.println(comparator2.compare(10,23));
    }
}
